﻿using MaterialDesignThemes.Wpf;
using NewLife;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using UIWindows.Commands;
using UIWindows.Enums;
using UIWindows.GlobalStatics;
using UIWindows.Models.Devices;
using UIWindows.Tools.Helper;
using UIWindows.Views;
using UIWindows.Views.Dialogs;
using XingLucifer.Devices;
using XingLucifer.IBase;
using XingLucifer.IBase.Enums;

namespace UIWindows.ViewModels
{
    public class RJ6902RViewModel
    {

        public TemporaryStatic Temporary { get; set; }
        public RJ6902RParametersModel RJ6902R { get; set; }
        public DeviceConfigStatic DeviceConfig { get; set; }
        private SystemConfigStatic _systemConfig;
        private UserConfigStatic _userConfig;
        public RJ6902RViewModel(DeviceConfigStatic deviceConfig, SystemConfigStatic systemConfig, UserConfigStatic userConfig, TemporaryStatic temporary)
        {
            DeviceConfig = deviceConfig;
            _systemConfig = systemConfig;
            _userConfig = userConfig;
            Temporary = temporary;
            RJ6902R = new RJ6902RParametersModel();

            var model = DeviceConfig.RJ6902R.FirstOrDefault(x => x.IsBeingUsed);
            if (model != null)
            {
                model.UpdateValue(RJ6902R);
            }
        }

        public DelegateCommand SendCMD => new DelegateCommand(async () =>
        {
            StringBuilder stringBuilder = new StringBuilder();
            if (RJ6902R.MyGuid != Guid.Empty)
            {
                var modeltest = DeviceConfig.RJ6902R.FirstOrDefault(x => x.MyGuid == RJ6902R.MyGuid);
                if (modeltest != null)
                {
                    stringBuilder.Append(RJ6902R.ContrastObject(modeltest));
                }
            }
            string bl = "true";
            if (!string.IsNullOrEmpty(stringBuilder.ToString()))
            {
                bl = (string)await stringBuilder.ToString().MessageDialogs(MessageLevelType.警告, true, Enums.PopUpTypes.Global, Visibility.Visible);
            }
            if (bl == "true")
            {
                var devices = DeviceConfig.DeviceList.Where(x => x.DeviceType == XingLucifer.IBase.Enums.DeviceTypes.RJ6902R_ShortCircuit);
                StringBuilder error = new StringBuilder();
                _ = DialogHost.Show(new LoadingDialogs(), PopUpTypes.Global.ToString()).ConfigureAwait(false);
                CancellationTokenSource cancellationToken = new CancellationTokenSource();
                await Task.Run(() =>
                {
                    foreach (var x in devices)
                    {
                        if (x.Index == 999 || x.Index == 0 || string.IsNullOrEmpty(x.IPCOM))
                        {
                            return;
                        }
                        byte[] bytes = ToBytes(RJ6902R);
                        try
                        {
                            $"[{x.IPCOM}] [{x.Port}] 执行链接".RunLog(MessageLevelType.信息);
                            ICommunication com = null;
                            if (x.IsSocket)
                            {
                                com = new TCPCom(_systemConfig.SCM.FinsIP, x.IPCOM, x.Port, x.DeviceType, x.Index, x.TaskType, x.ServiceName, cancellationToken, EndianTypes.Modbus_ABCD);
                            }
                            else
                            {
                                com = new SerialPortCom(_systemConfig.SCM.FinsIP, x.IPCOM, x.Port, System.IO.Ports.Parity.None, 8, System.IO.Ports.StopBits.One, x.DeviceType, x.Index, x.TaskType, x.ServiceName, cancellationToken, EndianTypes.Modbus_ABCD);
                            }
                            IDevices model = EquipmentFactory.NewSocketDevice(_systemConfig.SCM.FinsIP, x.IPCOM, x.Port, x.DeviceType, x.Index, x.TaskType, x.ServiceName, cancellationToken, com);
                            if (model == null)
                            {
                                return;
                            }
                            bool? bools = model.Open();
                            if (bools == null || !(bool)bools) {
                                error.AppendLine($"[{x.IPCOM}] [{x.Port}] 设备连接失败,请检查串口服务器!!!");
                                model.Close();
                                return;
                            }
                            $"[{x.IPCOM}] [{x.Port}]进入波形采集界面".RunLog(MessageLevelType.信息);
                            if (!SendCommand(com, new byte[] { 0x7B, 0x00, 0x08, 0x02, 0x0F, 0xE1, 0xFA, 0x7D }))
                            {
                                error.AppendLine("进入波形采集界面失败！！！");
                                return;
                            }
                            Thread.Sleep(500);
                            $"[{x.IPCOM}] [{x.Port}]发送设置".RunLog(MessageLevelType.信息);
                            if (!SendCommand(com, bytes))
                            {
                                error.AppendLine("发送设置失败！！！");
                                return;
                            }
                            Thread.Sleep(200);
                            $"[{x.IPCOM}] [{x.Port}]采集界面下启动采集命令".RunLog(MessageLevelType.信息);
                            if (!SendCommand(com, new byte[] { 0x7B, 0x00, 0x08, 0x02, 0x0F, 0xE2, 0xFB, 0x7D }))
                            {
                                error.AppendLine("采集界面下启动采集命令失败！！！");
                                return;
                            }
                            Thread.Sleep((int)((RJ6902R.RT * 1000) + 500));
                            $"[{x.IPCOM}] [{x.Port}]保存采集波形".RunLog(MessageLevelType.信息);
                            if (!SendCommand(com, new byte[] { 0x7B, 0x00, 0x08, 0x02, 0x0F, 0xE3, 0xFC, 0x7D }))
                            {
                                error.AppendLine("保存采集波形失败！！！");
                                return;
                            }
                            Thread.Sleep(200);
                            $"[{x.IPCOM}] [{x.Port}]返回测试界面".RunLog(MessageLevelType.信息);
                            if (!SendCommand(com, new byte[] { 0x7B, 0x00, 0x08, 0x02, 0x0F, 0x00, 0x19, 0x7D }))
                            {
                                error.AppendLine("返回测试界面失败！！！");
                                return;
                            }
                            model.Close();
                        }
                        catch (Exception ex)
                        {
                            $"[{x.IPCOM}] [{x.Port}]短路测试 配置发送异常{ex}".RunLog(MessageLevelType.错误);
                            error.AppendLine($"[{x.IPCOM}] [{x.Port}] {ex}");
                        }
                    }
                });
                cancellationToken.Cancel();
                _ = $"RJ6902R 测试仪 配置修改：{(string.IsNullOrEmpty(error.ToString()) ? "成功" : "失败,请检测短路仪器是否在测试界面，或是否已解锁！！！")}".MessageDialogs(MessageLevelType.信息, false, Enums.PopUpTypes.Global);
                if (string.IsNullOrEmpty(error.ToString()))
                {
                    RJ6902RParametersModel rj6902r = DeviceConfig.RJ6902R.FirstOrDefault(x => x.MyGuid == RJ6902R.MyGuid);
                    if (rj6902r != null)
                    {
                        rj6902r.UpdateTime = DateTime.Now;
                        rj6902r.UpdateName = _userConfig.LoginUser.Name;
                        RJ6902R.UpdateValue(rj6902r);
                    }
                    else
                    {
                        rj6902r = new RJ6902RParametersModel();
                        RJ6902R.UpdateValue(rj6902r);
                        rj6902r.MyGuid = Guid.NewGuid();
                        DeviceConfig.RJ6902R.Add(rj6902r);
                    }
                    DeviceConfig.SaveRJ6902R();
                    return;
                }
            }
            var model = DeviceConfig.RJ6902R.FirstOrDefault(x => x.IsBeingUsed);
            if (model != null)
            {
                model.UpdateValue(RJ6902R);
            }
            DeviceConfig.SaveRJ6902R();
        }, Enums.AuthorityTypes.工艺_参照);

        public DelegateCommand Empty => new DelegateCommand(() => new RJ6902RParametersModel().UpdateValue(RJ6902R), Enums.AuthorityTypes.工艺_参照);

        public DelegateCommand Delete => new DelegateCommand(async () =>
        {
            var model = DeviceConfig.RJ6902R.FirstOrDefault(x => x.MyGuid == RJ6902R.MyGuid);
            if (model != null 
            && (((string)await $"RJ6902 [{RJ6902R.Name}] 二次确认是否删除".MessageDialogs(MessageLevelType.警告, true, Enums.PopUpTypes.Global, Visibility.Visible)) == "true"))
            {
                DeviceConfig.RJ6902R.Remove(model);
                new RJ6902RParametersModel().UpdateValue(RJ6902R);
                DeviceConfig.SaveRJ6902R();
            }
        }, Enums.AuthorityTypes.工艺_参照);

        public DelegateCommand<RJ6902RParametersModel> MouseDoubleClick => new DelegateCommand<RJ6902RParametersModel>(sender =>
        {
            if (sender == null)
            {
                return;
            }
            sender.UpdateValue(RJ6902R);
        }, Enums.AuthorityTypes.工艺_参照);

        private byte[] ToBytes(RJ6902RParametersModel model)
        {
            ushort rt = (ushort)(model.RT * 10);
            byte[] bytes = new byte[]{
                0x7B, 0x00, 0x22, 0x02, 0x5A, 0xF2,
                0,0x02,
                0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
                (byte)(model.Voltage >> 8),(byte)model.Voltage,
                (byte)(model.Time >> 8),(byte)model.Time,
                (byte)((model.VD1 * 10) >> 8),(byte)(model.VD1 * 10),
                (byte)((model.VD2 * 10) >> 8),(byte)(model.VD2 * 10),
                (byte)(model.TL >> 8),(byte)model.TL,
                (byte)(model.TH >> 8),(byte)model.TH,
                (byte)(rt >> 8),(byte)rt,
                (byte)(model.R >> 8),(byte)model.R,
                0x00, 0x7D
            };
            int be = 0;
            for (int i = 1; i < bytes.Length - 2; i++)
            {
                be += bytes[i];
            }
            bytes[bytes.Length - 2] = (byte)be;
            return bytes;
        }

        private static bool SendCommand(ICommunication socket, byte[] bytes)
        {
            socket.Write(bytes);
            System.Threading.Thread.Sleep(50);
            bytes = socket.Read(128);
            if (bytes.Length < 9)
            {
                $"短路测试 协议通信无响应".RunLog(MessageLevelType.错误);
                return false;
            }
            if (bytes[0] == 0x7b && bytes[4] != 0x99 && bytes[8] == 0x7d)
            {
                return true;
            }
            string error = null;
            switch (bytes[6])
            {
                case 0x01: error = "校验和错误"; break;
                case 0x02: error = "命令类型错误"; break;
                case 0x03: error = "命令字错误"; break;
                case 0x04: error = "状态不符"; break;
                case 0x05: error = "参数错误"; break;
            }
            $"短路测试数值写入异常，错误类型：{error}，返回报文{BitConverter.ToString(bytes)} ".RunLog(MessageLevelType.警告);
            return false;
        }
    }
}
